home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / Sas-PPC / manual.txt < prev    next >
Encoding:
Text File  |  1999-12-03  |  16.1 KB  |  497 lines

  1. Table of Contents.
  2.  
  3.      Tools Created by the Install Script.
  4.         Compiler.
  5.         Libraries
  6.         Header Files
  7.      GCC Tools Required for ELF Executables
  8.      Compiling and Linking
  9.         Alignment Issues
  10.         ELF objects and executables
  11.                Compatibility with GCC 
  12.         Hunk objects and executables
  13.             Mixing 68k and PPC Code
  14.         ELF vs. HUNK, which should I use? 
  15.      Library Routines for sharing memory with 68k programs.
  16.      Debugging with CPRPPC     
  17.      Limitations
  18.      Examples
  19.         Calc
  20.      Shared Libraries
  21.         Shared Library examples
  22.  
  23.  
  24. Tools created by the Install Script.
  25.  
  26. The install script does not modify any of the existing 68k
  27. tools. Instead, it creates a new compiler and toolset for
  28. generating PPC code. The files associated with the compiler
  29. are: 
  30.             scppc
  31.             sc1ppc.library
  32.             sc2ppc.library
  33.             sc2ppch.library
  34.             scpeep.library
  35.             scgoppc.library
  36.             cprppc
  37.             slinkppc
  38.             
  39. The install script also creates runtime liibraries; scppc.a
  40. is the ELF format C runtime, and scppc.lib is the HUNK format
  41. verison. The C++ libraries are sccxxppc.a and sccxxppc.lib.
  42.  
  43. Some of the 68k header files are patched to provide the necessary
  44. changes for PPC support. Also, new headers are included that provide 
  45. inline functions for access to OS routines. These new headers are
  46. placed in sc:ppcinclude.
  47.  
  48.  
  49. GCC Tools Required to Create ELF Executables.
  50.  
  51. To create ELF executables, you will also need the linker (ld) from
  52. the GCC archive. If you plan to make link libraries, you will
  53. also need the ELF libraries (ar). These tools can be found on
  54. the Phase 5 CD, or on ftp.ninemoons.com in the 'binutils'
  55. archive.
  56.  
  57.  
  58. Compiling.
  59.  
  60. Alignment issues:
  61.  
  62. By default, the PPC compiler aligns items on natural boundaries. This
  63. differs from the 68k compiler (which aligns items on at most 2 byte 
  64. boundaries). The PPC compiler supports the following #pragma to change
  65. the alignment:
  66.  
  67. #pragma options align=mac68k
  68. #pragma options align=power
  69. #pragma options align=reset
  70.  
  71. At the end of any header file, the alignemt is reset back to what it
  72. was before the header file was included.
  73.  
  74. INCLUDE: vs PPCINCLUDE:
  75.  
  76. The compiler will search PPCINCLUDE: first, followed by INCLUDE:. Any
  77. header file that is pulled from INCLUDE: will automatically set the 
  78. alignment to 68k style.
  79.  
  80.  
  81. ELF Objects and Executables
  82.  
  83. To create PowerPC object modules, use the SCPPC driver instead
  84. of the SC driver. By default, the objects created by SCPPC are
  85. ELF format.
  86.  
  87. Compatibility with GCC 
  88.  
  89. I have tried to make the compiler compatible with GCC objects. As far
  90. as I know, there are only two areas where SAS/C is not compatible.
  91.  
  92.   1) va_start(), va_arg(), and the va_list structure are not compatible.
  93.      You can call a varargs function from one compiler to the other,
  94.      but you cannot pass a structure of type va_list between modules
  95.      compiled with different compilers.
  96.  
  97.   2) Passing and returning structures by value are not compatible.
  98.  
  99.  
  100. Linking ELF Executables
  101.  
  102. To link with the SAS/C standard library, you must use THREE modules
  103. (as opposed to TWO in the 68k version) besides the objects for your
  104. own code. An example link command would look like:
  105.  
  106. ppc-amigaos-ld -r -o exename lib:c_ppc.o <YOUR OBJECTS GO HERE> lib:scppc.a lib:end.o
  107.  
  108.  
  109. c_ppc.o is equivalent to c.o in the 68k version. Source code is also provided
  110.         for this module (c_ppc.c)
  111.         
  112. scppc.a is equivalent to sc.lib and scm.lib.
  113.  
  114. end.o   is a new addition, required to make autoinitializers work. In the 68k
  115.         version SLINK performs this extra work.
  116.  
  117.  
  118. If you are linking an executable that contains C++ code, then add lib:scppccxx.a
  119. before lib:scppc.a on the link line, eg
  120.  
  121. ppc-amigaos-ld -r -o exename lib:c_ppc.o <YOUR OBJECTS GO HERE> lib:scppccxx.a lib:scppc.a lib:end.o
  122.  
  123. Note: The EXECUTE bit is not set by 'ppc-amigados-ld', so you need
  124. to set it yourself, eg:
  125.  
  126. protect exename +e
  127.  
  128. To run an ELF executable, you either need to use the RUNELF program 
  129. (included in this archive, sc:c/runelf), or the LoadSeg patch provided
  130. by Phase 5.
  131.  
  132.  
  133. Hunk Objects and Executables
  134.  
  135. Firstly, these HUNK style objects are NOT compatible with WarpOS. They
  136. run only with the Phase 5 kernel, ppc.library.
  137.  
  138. To use HUNK objects instead of ELF objects, compile with the 
  139. HUNKOBJ option to SCPPC. To link, use SLINKPPC with the option PPC
  140. to link. SLINKPPC should be backward compatible with the previous 6.58 
  141. version of the 68k SLINK, but I have created a new exe for now, just to 
  142. insure that I don't break the 68k version. Also, SLINKPPC cannot be used 
  143. to strip debug information from execuatbles yet. You can relink the
  144. objects with the NODEBUG option to get an executable without debug
  145. information.
  146.  
  147. When you create a HUNK style executable, the startup code is still
  148. 68k code. The 68k code handles the Workbench startup message, and
  149. command line arguments. It then starts a PPC task, and runs the rest
  150. of the PPC program.
  151.  
  152. Here's an example:
  153.  
  154. scppc HUNKOBJ test.c
  155. SLINKPPC PPC FROM lib:c.o test.o to test LIB LIB:scppc.lib
  156.  
  157.  
  158. You can also link directly from the SCPPC driver, ie:
  159.  
  160. scppc HUNKOBJ test.c LINK
  161.  
  162.  
  163.  
  164. Mixing 68k and PPC code.
  165.  
  166. Every HUNK style executable is actually a mixed 68k and PPC executable.
  167. By default, only the startup code is 68k, howeever, it is possible
  168. for the PPC to call other 68k functions in the HUNK executable through
  169. the PPCCallM68k() kernel function. It is also possible to share global
  170. data between the PPC and 68k, however, extreme care should be taken
  171. to flush caches properly.
  172.  
  173. The 68k compiler adds an underscore '_' to all global symbols (except
  174. regargs functions, where it add '@'). The PPC compiler does not add any
  175. special leading characters.  Therefore, if you write a 68k function, such
  176. as:
  177.  
  178. foo()
  179. {
  180. }
  181.  
  182. In PPC code, you can call this 68k function by doing:
  183.  
  184. extern int _foo();
  185. bar()
  186. {
  187.     PPCCallM68k(_foo, ...);
  188. }
  189.  
  190.  
  191. Format of a HUNK style executable.
  192.  
  193. This diagram shows the basic layout of a PPC Hunk style execuatble.
  194.  
  195.    -------------------------------
  196.    |      c.o  (68k)             |
  197.    |     __main() (68k)          |   Code Hunk.
  198.    |                             |
  199.    |    PPC code                 |
  200.    |                             |
  201.    |                             |
  202.    -------------------------------
  203.    |                             |
  204.    | Near Data section (TOC)     |   Data Hunk
  205.    | A4 and R13 point here       |
  206.    |                             |
  207.    -------------------------------
  208.    |                             |
  209.    | Far data section            |   Data Hunk
  210.    |                             |
  211.    |                             |
  212.    -------------------------------
  213.    |                             |
  214.    | Far BSS section             |   BSS Hunk
  215.    |                             |
  216.    -------------------------------
  217.    | Slink generated ELF exe     |
  218.    | With entry point, and       |   Code Hunk
  219.    | branches to Kernel routines |
  220.    |                             |
  221.    -------------------------------
  222.  
  223. The program starts like a normal 68k executable, running the
  224. standard startup code. The code in __main() (found in 
  225. source/ppc__main.c) loads the SLINK generated ELF stub from
  226. memory (the SLINK generated symbol '_ElfObject' points the
  227. the in memory ELF stream. The address of the PPC code is saved
  228. in the global variable '_ElfEntry'. It then creates a PPC task and
  229. waits for it to finish. The ELF entry point takes four parameters:
  230. 1) command line  2) WB message  3) Near Data (TOC) address
  231. 4) PPC code to jump to.
  232.  
  233. Calls to the ppc.library kernel are routed (by SLINK) to an offest
  234. relative to '_ElfEntry', so the kernel function addresses can be 
  235. resolved by the ELF loader.
  236.  
  237.  
  238.  
  239.  
  240. ELF vs. HUNK, which should I use?
  241.  
  242. There's no single best answer to this question. That is why I have
  243. made the compiler generate both formats. Below, I tried to give some
  244. advantages of each form.
  245.  
  246. ELF Advantages.
  247.  
  248.   1) ELF is the format that Phase 5 has choosen. This is probably the
  249.      single biggest reason to use ELF. Phase 5 has stated that to the
  250.      best way to insure that your program will run on the next Phase 5
  251.      machine/OS is to use ELF.
  252.      
  253.   2) ELF is a standard format. There are many tools available to 
  254.      manipulate ELF files.
  255.  
  256.   3) There are third party libraries available in the ELF format.
  257.      If you use ELF, you can link with them. One example is libmoto.a,
  258.      a set of optimised math routines.
  259.  
  260.  
  261. HUNK Advantages.
  262.  
  263.   1) It is not necessary to have the Elf LoadSeg() patch running, or
  264.      to use 'runelf' to run this type of executable.
  265.      
  266.   2) It is easier to mix 68k and PPC code in a single executable.
  267.   
  268.   3) Amiga style shared libraries are possible (see my proposed 
  269.      format of these below).
  270.      
  271.   4) If you use C++, only the HUNK version can do implicit templates
  272.      because of the necessary linker support. 
  273.  
  274.  
  275. Library Routines for sharing memory with 68k programs.
  276.  
  277. These routines use PPCCallM68k() and use the 68k to perform the
  278. read and write, so it is safe to read and write system structures 
  279. with these routines.
  280.  
  281. void Write68kLong(long value, void *ptr);
  282. void Write68kShort(long value, void *ptr);
  283. void Write68kChar(long value, void *ptr);
  284. long Read68kLong(void *ptr);
  285. long Read68kShort(void *ptr);
  286. long Read68kChar(void *ptr);
  287.  
  288.  
  289. Debugging With CPRPPC
  290.  
  291. CPRPPC is able to debug both ELF and HUNK style executables with
  292. full source level debugging. It can also debug Workbench programs.
  293.  
  294.  
  295. Debugging ELF Exectuables.
  296.  
  297. To debug an ELF executable, simply do:
  298.  
  299. cprppc exename <arguments>
  300.  
  301. CPRPPC will start the program 'exename' in the same way that RUNELF
  302. starts the program.
  303.  
  304. CPRPPC is also able to catch the next PPC task started. This is usefull
  305. for debugging programs started under Workbench, or from a different 
  306. 68k task. To do this, start CPRPPC with the -catch option. ie
  307.  
  308. CPRPPC -catch <exename>
  309.  
  310. Then go to another shell or use WorkBench to start the PPC program
  311. normally.  CPRPPC will gain control of the PPC task.
  312.  
  313.  
  314. Debugging HUNK executables.
  315.  
  316. To debug a HUNK style executable, you will need to have SEGTRACKER running.
  317. Once it's running, use the -catch option to catch the PPC task.  In one
  318. shell, do:
  319.  
  320. CPRPPC -catch <exename>
  321.  
  322. Then in another shell, start the program to be debugged.
  323.  
  324.  
  325. Limitations:
  326.  
  327. Currently, for ELF format, only the compiler and debugger are provided.
  328. You will need to use the linker provided with GCC.
  329.  
  330. This compiler is compatible with GCC with the exception of passing
  331. structures by value.
  332.  
  333. GST's are not supported in the PPC compiler.
  334.  
  335. Placing strings in the code section is not supported. The compiler
  336. will ignore options to place strings in the code section, however,
  337. it will merge common strings with the STRMERGE option.
  338.  
  339. The concept of near, far, and chip data is only supported in the
  340. HUNK version of the compiler. All data in the ELF compiler is treated as 
  341. far.
  342.  
  343.  
  344. C++ Limitations:
  345.  
  346. You should use the C++ header files that are included in the Experimental
  347. C++ patch, not the 6.50 C++ header files. 
  348.  
  349. C++ supports the INCLUDE: vs PPCINCLUDE: alignment differences, but it
  350. does not support #pragma options align=...
  351.  
  352.  
  353. Examples:
  354.  
  355. There are two examples in the 'examples' directory. The first is a simple 
  356. "Hello World" program that also prints out its arguments. The second is a 
  357. simple RPN calculator, that I use as the first test case whenever I create
  358. a new compiler.
  359.  
  360. Also, in that directory is a small utility to execute ELF programs, called 
  361. "runelf". This program runs ELF programs in the same manner as CPRPPC, 
  362. with respect to setting up stdio and command line arguments.
  363.  
  364.  
  365. Simply CD to the examples directory, and run smake.
  366. Then try
  367.  
  368.    runelf hello.elf 1 2 3 4 5
  369.    
  370. or
  371.  
  372.    cprppc hello.elf 1 2 3 4 5
  373.    
  374.  
  375. To use the calculator, try something like
  376.  
  377. runelf calc.elf
  378.  
  379. 1 2 +
  380.  
  381. You can type '?' to get the list of functions it has.
  382.  
  383.  
  384.  
  385. Shared Libraries
  386.  
  387. The following is my current plan to implement PPC Shared libraries.
  388. The goals of this form of shared library are as follows.
  389.  
  390. 1) Compatible with current Amiga shared library format.
  391.  
  392. 2) Able to be called from either 68k or PPC code. This would
  393.    mean that old program could benefit from new PPC shared libraries.
  394.  
  395. 3) Provide ability for the shared library to run without
  396.    a PPC chip (may require extra coding, but it will be possible).
  397.  
  398.        68k Jump table -A6                Linker generated stub in Far data
  399.      |-----------------------|           ---------------
  400.      |_______________________|           |_____________|---------+
  401.      |_______________________|   ------->| JMP         | ---+    |
  402.      |_______________________|           ---------------    |    |
  403. A6-> |-----------------------|                              |    |
  404.      |                       |                              |    |
  405.      |                       |                              |    |
  406.      |                       |                              |    |
  407.      -------------------------                              |    |
  408.                                                             |    |
  409.       Near Data and PPC TOC                                 |    |
  410.           +A6                                               |    |
  411.                                      -------------------    |    |
  412.                                      |  68k function   |  <-+    |
  413.                                      |                 |         |
  414.                                      |                 |         |
  415.                                      |                 |         |
  416.                                      -------------------         |
  417.                                                                  |
  418.                                                                  |
  419.                                                                  |
  420.                                                                  |
  421.                                      -------------------         |
  422.                                      |  PPC Function   |     <---+
  423.                                      |                 |
  424.                                      |                 |
  425.                                      |                 |
  426.                                      |                 |
  427.                                      -------------------
  428.  
  429.  
  430. LibOpen() will create a PPC Task for each OpenLibrary(). That PPC
  431. task will then be put in a wait loop waiting for msg's that signify
  432. a function call into the PPC code.
  433.  
  434. 68k code will call functions in this library through the #pragma
  435. mechanism. The 68k functions will then use the function dispatch
  436. to send a message to the PPC task.
  437.  
  438. PPC code will dereference the jump table, then dereference -4 from
  439. the 68k stub to get the address of the PPC function in the library.
  440.  
  441. LibClose() will send a termination message to the PPC Task in the
  442. library.
  443.  
  444.  
  445.  
  446. Shared Library Examples
  447.  
  448.  
  449. There are three examples in the archive, in the directories 
  450. 'samplelib1', 'samplelib2', and 'samplelib3'. 
  451.  
  452. NOTE: with ppc.library V45.20 'samplelib1' is not stable for 
  453. unknown reasons. It does work with later experimental versions. 
  454. Also, it works when stepping through this example with CPR & 
  455. CPRPPC, so there must be a race condition somewhere.
  456.  
  457. The other two examples work fine with V45.20.
  458.  
  459.  
  460.  
  461. samplelib1
  462.  
  463. This version creates a separate global data area for each 
  464. opener of the library. Also, a PPC task is created in
  465. LibOpen() for each opener.
  466.  
  467. When PPC code makes a call into the library, the process that
  468. made the call executes the PPC code in the library directly.
  469. There is no messages passed.
  470.  
  471. When 68k code makes a call into the library, a message is passed
  472. to the PPC task created in LibOpen, and the code executes in
  473. that task. Note: Only 8 parameters are currently passes, and
  474. they must be some integer or pointer type, ie no doubles, floats,
  475. or structs passed by value. Typically, Amiga libraries don't
  476. do that anyway.
  477.  
  478.  
  479.  
  480. samplelib2
  481.  
  482. There is no PPC task created in this version, and global data is
  483. shared between all openers of the library. In this form, all
  484. code must be duplicated in 68k and PPC form.
  485.  
  486.  
  487. samplelib3
  488.  
  489. This version is like samplelib1, in that it has a separate copy
  490. of global data for each task, but it does not create the function
  491. dispatcher to let 68k code call the PPC routines. The 68k entry 
  492. points are simply do nothing stubs. The LibOpen creates a syncronous
  493. PPC task to run the autoinitializers, and LibClose does creates another
  494. to run the autoterminators.
  495.  
  496. The remaining PPC entrypoints execute in the openers task.
  497.